package com.xiyuan.smartutils.lambda;

import com.xiyuan.smartutils.Types;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.regex.Pattern;

/**
 * the description for class Lambda
 *
 * @author xiyuan-lgz 2024-06-08 @version v1.0.0 新建与整理
 */
@SuppressWarnings("unchecked")
public interface Lambda extends Serializable {
    final Pattern RETURN_TYPE_PATTERN = Pattern.compile("\\(.*\\)(L?.*);?");
    
    default SerializedLambda getSerializedLambda() {
        return LBDA.getSerializedLambda(this);
    }
    
    /**
     * 获取Lambda 方法返回值类型，返回值为为包装类型，比如：方法定义为 返回int,那么会返回 java.lang.Integer
     * 如果需要返回原始类型则使用 {@link Lambda#getOriginalReturnType}
     */
    default <E> Class<E> getWrapReturnType() {
        return (Class<E>) Types.getWrapType(getReturnType());
    }
    
    /**
     * 获取Lambda 方法原始返回值类型
     *
     */
    default <E> Class<E> getReturnType() {
        return LBDA.getReturnType(getSerializedLambda());
    }
    
    /**
     * 获取实例提供者类型
     *
     * <pre>
     * 例如：
     *
     *  class A {
     *      private Integer f1;
     *      public Integer getF1() {return f1;}
     *  }
     *  class A1 extends A {
     *  }
     *
     * getInstanceProviderType<A1::getF1>   返回 Class< A1 >
     * </pre>
     */
    default <E> Class<E> getInstanceProviderType() {
        return LBDA.getInstanceProviderType(getSerializedLambda());
    }
    
    
    /**
     * 获取Lambda表达式的参数类型
     */
    default Class<?>[] getParameterTypes() {
        return LBDA.getParameterTypes(getSerializedLambda());
    }
    
    /**
     * 获取提供盖房发的实现类
     */
    default <E> Class<E> getImplClass() {
        return LBDA.getImplClass(getSerializedLambda());
    }
    
    default Method getImplMethod() {
        return LBDA.getImplMethod(getSerializedLambda());
    }
}
